package domain;

import java.util.ArrayList;

/**
 * @author Carlos García Márquez
 * @author Brian Carvajal Meza
 * @author Andreu Marimon Aguadé
 */
class Trie<T> {

    private TrieNode<T> _root;

    /**
     * Crea un trie buit
     */
    protected Trie() {
        _root = new TrieNode<T>();
    }

    protected Trie(TrieNode<T> root) {
        _root = root;
    }

    /**
     * Guarda un valor al {@code Trie} i el marca com a valor final.
     * @param id clau amb la que es guarda el valor.
     * @param value valor a guardar al trie.
     */
    protected void put(String id, T value) {
        _root.put(id, value);
    }

    /**
     * Guarda un valor al {@code Trie} sense marcar-lo com a valor final.
     * @param id clau amb la que es guarda el valor.
     * @param value valor a guardar al trie.
     */
    protected void assign(String id, T value) {
        _root.assign(id, value);
    }

    /**
     * Elimina el valor amb clau {@code id}
     * @param id Clau del node a esborrar
     */
    protected void delete(String id) {
        _root.delete(id);
    }
    /**
     * @param id clau que es vol comprovar si existeix.
     * @return Retorna {@code true} si existeix la clau al node.
     */
    protected Boolean exists(String id) {
        return _root.get(id) != null;
    }

    /**
     * @return Retorna {@code true} si el que hi ha a clau es final.
     */
    protected Boolean isFinal() {
        return _root.isFinal();
    }

    /**
     * @return Retorna l'etiqueta del node arrel.
     */
    protected String getLabel() {
        return _root.getLabel();
    }

    /**
     * @param id Clau a cercar.
     * @return Retorna el valor {@code T} guardat amb la clau {@code id}
     */
    public T get(String id) {
        return _root.get(id);
    }

    /**
     * @return Llista de tots els {@code: T} que hi ha al Trie.
     */
    public ArrayList<T> getAll() {
        ArrayList<T> all = _root.getAll();
        //all.add(_root.getValue());
        return all;
    }

    /**
     * Retorna el subTrie que té com a arrel el node final de path.
     *
     *
     * @return Trie de T que té com a arrel el final de path
     */

    protected Trie<T> getTrie(String path) {
        Trie<T> trieFinal =  new Trie<T> (_root.getNode(path));
        return trieFinal;
    }

    /**
     * @return Llista dels fills del node arrel en forma de Trie.
     */
    public ArrayList<Trie<T>> getChildTries() {
        ArrayList<Trie<T>> childTries = new ArrayList<Trie<T>>();
        for (TrieNode<T> node : _root.getChildNodes()) {
            childTries.add(new Trie<T>(node));
        }
        return childTries;
    }

    @Override
    public java.lang.String toString() {
        // TODO imprimir en format llegible
        return "Trie,\n" + _root.toString();
    }
}
